package com.wxd.modules.function.service.impl;

import com.alibaba.fastjson.JSONArray;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.google.common.reflect.TypeToken;
import com.wxd.annotation.DataFilter;
import com.wxd.modules.common.entity.Cause;
import com.wxd.modules.common.entity.Gender;
import com.wxd.modules.common.entity.Status;
import com.wxd.modules.common.redis.FunEmpRedis;
import com.wxd.modules.common.service.CauseService;
import com.wxd.modules.common.service.GenderService;
import com.wxd.modules.common.service.StatusService;
import com.wxd.modules.function.dao.EmpDao;
import com.wxd.modules.function.entity.EmpEntity;
import com.wxd.modules.function.entity.EmpStatusChange;
import com.wxd.modules.function.entity.SwitchDataChange;
import com.wxd.modules.function.entity.department.JWDEmpEntity;
import com.wxd.modules.function.entity.department.JWDEntity;
import com.wxd.modules.function.entity.department.KYDEmpEntity;
import com.wxd.modules.function.entity.department.KYDEntity;
import com.wxd.modules.function.service.EmpService;
import com.wxd.modules.function.service.EmpStatusChangeService;
import com.wxd.modules.function.service.SwitchDataChangeService;
import com.wxd.modules.function.service.department.JwdService;
import com.wxd.modules.function.service.department.KydService;
import com.wxd.modules.sys.entity.SysDeptEntity;
import com.wxd.modules.sys.entity.SysUserEntity;
import com.wxd.modules.sys.service.SysDeptService;
import com.wxd.utils.Constant;
import com.wxd.utils.PageUtils;
import com.wxd.utils.Query;
import com.wxd.validator.ValidatorUtils;
import com.wxd.validator.group.UpdateGroup;
import org.apache.commons.lang.StringUtils;
import org.apache.shiro.SecurityUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.util.*;

/**
 * 员工表
 */
@Service("empService")
public class EmpServiceImpl extends ServiceImpl<EmpDao, EmpEntity> implements EmpService {
    @Autowired
    private SysDeptService sysDeptService;
    @Autowired
    private EmpStatusChangeService empStatusChangeService;
    @Autowired
    private CauseService causeService;
    @Autowired
    private GenderService genderService;
    @Autowired
    private StatusService statusService;
    @Autowired
    private JwdService jwdService;
    @Autowired
    private KydService kydService;
    @Autowired
    private FunEmpRedis funEmpRedis;
    @Autowired
    private RedisTemplate redisTemplate;

    @Autowired
    private SwitchDataChangeService switchDataChangeService;
   /*在册*/
    @Override
    @DataFilter(subDept = true, user = false)
    public PageUtils queryPage(Map<String, Object> params) {
        String empName = (String) params.get("name");
        String deptIdStr= (String) params.get("deptId");
        String dateStart=(String)params.get("dateStart");
        String dateEnd=(String)params.get("dateEnd");
        Long deptIdLong;
        String parentDept;
        /*根据部门进行人员筛选*/
        if(StringUtils.isNotBlank(deptIdStr)) {
            IPage<EmpEntity> page=null;
            //先在缓存中查找，如果缓存中不存在，再从数据库去查找。同时更新到缓存。
            parentDept= queryParentDeptByDeptId(Long.valueOf(deptIdStr));
            if(funEmpRedis.get(parentDept+":"+deptIdStr)!=null)
            {
                System.out.println(deptIdStr+"---缓存中存在");
                page = new Page<EmpEntity>();
                List<EmpEntity> empEntities = funEmpRedis.get(parentDept+":"+deptIdStr);
                page.setRecords(empEntities);
            }
            else {
                System.out.println(deptIdStr+"--缓存中不存在");
                //根据部门ID将部门下的所有人员查找出来
                List<Long> deptIdList = null;
                if (StringUtils.isNotBlank(deptIdStr)) {
                    deptIdLong = Long.valueOf(deptIdStr);
                    deptIdList = sysDeptService.getSubDeptIdList(deptIdLong);
                    deptIdList.add(deptIdLong);
                }
                page = this.page(
                        new Query<EmpEntity>().getPage(params),
                        new QueryWrapper<EmpEntity>()
                              /* .like(StringUtils.isNotBlank(empName), "emp_name", empName)*/
                                .between(StringUtils.isNotBlank(dateStart), "date", dateStart, dateEnd)
                                .in(deptIdList != null, "dept_id", deptIdList)
                                .in("status", 0, 5)
                                .apply(params.get(Constant.SQL_FILTER) != null, (String) params.get(Constant.SQL_FILTER))
                );
                /*补全人员信息*/
                for (EmpEntity empEntity : page.getRecords()) {
                    SysDeptEntity sysdeptEntity = sysDeptService.getById(empEntity.getDeptId());
                    empEntity.setDeptName(sysdeptEntity.getName());
                }
                /*将信息保存在缓存之中*/
                funEmpRedis.saveOrUpdate(parentDept+":"+deptIdStr,page.getRecords());
            }
            /*当按名字模糊查询时，从已得到的部门人员里面去查询这个名字*/
            if(StringUtils.isNotBlank(empName)) {
                List<EmpEntity> list = new ArrayList<EmpEntity>();
                for (EmpEntity empEntity : page.getRecords()) {
                    if (empEntity.getEmpName().contains(empName)) {
                        list.add(empEntity);
                    }
                }
                page.setRecords(list);
            }
            return new PageUtils(page);
        }
        return new PageUtils();
    }
    /*在岗*/
    @Override
    @DataFilter(subDept = true, user = false)
    public PageUtils queryPageExist(Map<String, Object> params) {
        String empName = (String) params.get("name");
        String deptIdStr= (String) params.get("deptId");
        Long deptIdLong;
        if(StringUtils.isNotBlank(deptIdStr)) {
            //根据部门ID将部门下的所有人员查找出来
            List<Long> deptIdList = null;
            if (StringUtils.isNotBlank(deptIdStr)) {
                deptIdLong = Long.valueOf(deptIdStr);
                deptIdList = sysDeptService.getSubDeptIdList(deptIdLong);
                deptIdList.add(deptIdLong);
            }
            IPage<EmpEntity> page = this.page(
                    new Query<EmpEntity>().getPage(params),
                    new QueryWrapper<EmpEntity>()
                            .like(StringUtils.isNotBlank(empName), "emp_name", empName).in(deptIdList != null, "dept_id", deptIdList).eq("status", 0)
                            .apply(params.get(Constant.SQL_FILTER) != null, (String) params.get(Constant.SQL_FILTER))
            );
            for (EmpEntity empEntity : page.getRecords()) {
                SysDeptEntity sysdeptEntity = sysDeptService.getById(empEntity.getDeptId());
                empEntity.setDeptName(sysdeptEntity.getName());
            }
            return new PageUtils(page);
        }
        return new PageUtils();
    }
    /*不在岗*/
    @Override
    @DataFilter(subDept = true, user = false)
    public PageUtils queryPageNot(Map<String, Object> params) {
        String empName = (String) params.get("name");
        String deptIdStr= (String) params.get("deptId");
        Long deptIdLong;
        if(StringUtils.isNotBlank(deptIdStr)) {
            //根据部门ID将部门下的所有人员查找出来
            List<Long> deptIdList = null;
            if (StringUtils.isNotBlank(deptIdStr)) {
                deptIdLong = Long.valueOf(deptIdStr);
                deptIdList = sysDeptService.getSubDeptIdList(deptIdLong);
                deptIdList.add(deptIdLong);
            }
            IPage<EmpEntity> page = this.page(
                    new Query<EmpEntity>().getPage(params),
                    new QueryWrapper<EmpEntity>()
                            .like(StringUtils.isNotBlank(empName), "emp_name", empName)
                            .in(deptIdList != null, "dept_id", deptIdList)
                            .eq("status", 5)
                            .apply(params.get(Constant.SQL_FILTER) != null, (String) params.get(Constant.SQL_FILTER))
            );
            for (EmpEntity empEntity : page.getRecords()) {
                SysDeptEntity sysdeptEntity = sysDeptService.getById(empEntity.getDeptId());
                List<EmpStatusChange> empStatusChanges = empStatusChangeService.queryEmpStatusChange(empEntity.getEmpId());
                if (empStatusChanges.size() > 0) {
                    Cause cause = causeService.queryValue(empStatusChanges.get(0).getCause());
                    empEntity.setCauseStr(cause.getCauseValue());
                    empEntity.setChangeDate(empStatusChanges.get(0).getChangeDate());
                }
                empEntity.setDeptName(sysdeptEntity.getName());
            }
            return new PageUtils(page);
        }
        return new PageUtils();
    }

    @Override
    public List<EmpEntity> queryEmp(Long[] empIds) {
        List<EmpEntity> empList=new ArrayList<>();
        for(Long empId:empIds)
        {
            empList.add(baseMapper.selectById(empId));
        }
        return  empList;
    }

    @Override
    @DataFilter(subDept = true, user = false)
    public PageUtils queryStatisticsPage(Map<String, Object> params) {
        String empName = (String) params.get("name");
        String deptIdStr= (String) params.get("deptId");
        String dateStart=(String)params.get("dateStart");
        String dateEnd=(String)params.get("dateEnd");
        String office=(String)params.get("office");
        String genderStr= (String) params.get("gender");
        String statusStr= (String) params.get("status");
        String educationStr= (String) params.get("education");
        if(educationStr!=null)
        {
            educationStr=educationStr.substring(1, educationStr.length() - 1);
        }
        String backgroundStr= (String) params.get("background");
        if(backgroundStr!=null) {
            backgroundStr = backgroundStr.substring(1, backgroundStr.length() - 1);
        }
        List<String> education=null;
        if(StringUtils.isNotBlank(educationStr))
        {
            education = Arrays.asList(educationStr.replace("\"", "").split(","));
        }
        List<String> background=null;
        if(StringUtils.isNotBlank(backgroundStr))
        {
            background = Arrays.asList(backgroundStr.replace("\"", "").split(","));
        }
        Integer gender=null,status=null;
        if(StringUtils.isNotBlank(genderStr))
        {
            gender = Integer.valueOf(genderStr);
        }
        if(StringUtils.isNotBlank(statusStr))
        {
           status = Integer.valueOf(statusStr);
        }
        //根据部门ID将部门下的所有人员查找出来
        Long deptIdLong;
        List<Long> deptIdList = null;
        if(StringUtils.isNotBlank(deptIdStr))
        {
            deptIdLong= Long.valueOf(deptIdStr);
            deptIdList =sysDeptService.getSubDeptIdList(deptIdLong);
            deptIdList.add(deptIdLong);
        }
        IPage<EmpEntity> page = this.page(
                new Query<EmpEntity>().getPage(params),
                new QueryWrapper<EmpEntity>()
                        .like(StringUtils.isNotBlank(empName),"emp_name", empName)
                        .in(deptIdList!=null,"dept_id",deptIdList)
                        .in(education!=null,"education",education)
                        .in(background!=null,"political_background",background)
                        .eq(status!=null,"status",status)
                        .between(StringUtils.isNotBlank(dateStart),"date",dateStart,dateEnd)
                        .eq(StringUtils.isNotBlank(office),"office",office)
                        .eq(gender!=null,"gender",gender)
                        .apply(params.get(Constant.SQL_FILTER) != null, (String)params.get(Constant.SQL_FILTER))
        );
        for(EmpEntity empEntity:page.getRecords())
        {
            SysDeptEntity sysdeptEntity = sysDeptService.getById(empEntity.getDeptId());
            empEntity.setDeptName(sysdeptEntity.getName());
        }
        return new PageUtils(page);
    }
    @Override
    public String queryParentDept(Long empId) {
        EmpEntity emp = this.getById(empId);
        List<Long> parentIdList = sysDeptService.queryParentIdList(emp.getDeptId());
        for(Long deptId:parentIdList)
        {
            if ((deptId+"").equals(Constant.DeptType.JWD.getValue()) ) {
                return "jwd";
            }
            if ((deptId+"").equals(Constant.DeptType.KYD.getValue())) {
                return "kyd";
            }
        }
        return null;
    }
    public String queryParentDeptByDeptId(Long deptIds) {
        List<Long> parentIdList = sysDeptService.queryParentIdList(deptIds);
        for(Long deptId:parentIdList)
        {
            if ((deptId+"").equals(Constant.DeptType.JWD.getValue()) ) {
                return "jwd";
            }
            if ((deptId+"").equals(Constant.DeptType.KYD.getValue())) {
                return "kyd";
            }
        }
        return null;
    }

    @Override
    public JWDEntity queryAllJWDEmpById(Long empId) {
        EmpEntity emp = queryBaseEmp(empId);
        JWDEmpEntity jwdEmpEntity = jwdService.queryJwdEmp(empId);
        JWDEntity jwdEntity=new JWDEntity();
        jwdEntity.setEmpEntity(emp);
        jwdEntity.setJwdEmpEntity(jwdEmpEntity);
        return jwdEntity;
    }
    @Override
    public KYDEntity queryAllKYDEmpById(Long empId) {
        EmpEntity emp = queryBaseEmp(empId);
        KYDEmpEntity kydEmpEntity = kydService.queryKydEmp(empId);
        KYDEntity kydEntity=new KYDEntity();
        kydEntity.setEmpEntity(emp);
        kydEntity.setKydEmpEntity(kydEmpEntity);
        return kydEntity;
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public void updateEmp(Map<String,Object> params) {
        String deptParent = (String)params.get("deptParent");//得到的是字符串
        String text = JSONArray.toJSONString(params.get("emp"));//得到的是JSON格式
        EmpEntity emp = JSONArray.parseObject(text,EmpEntity.class);
        ValidatorUtils.validateEntity( emp, UpdateGroup.class);
        this.updateById(emp);

        /*记录变化的信息,根据人员信息的变化更新到其他子系统*/
        //用户名
       /* String username = ((SysUserEntity) SecurityUtils.getSubject().getPrincipal()).getUsername();
        SwitchDataChange dataChange=new SwitchDataChange();
        dataChange.setEmpId(emp.getEmpId());
        dataChange.setIdCard(emp.getIdCard());
        dataChange.setDeptId(emp.getDeptId());
        dataChange.setOperator(username);
        dataChange.setDate(new Date());
        switchDataChangeService.save(dataChange);*/
        /*缓存一致性
        * 当人员数据发生变化时
        * （1）更新到数据库
        * （2）更新缓存
        *   1）删除缓存
        *   2）下次将查找出来的数据保存到缓存
        */
        /*当某个站段人员数据发生变化时，就清除该站短所有缓存*/
        String parentDept = queryParentDept(emp.getEmpId());
        Set<String> keys = redisTemplate.keys("fun:emp:"+parentDept+"*");
        System.out.println("所有的缓存key"+redisTemplate.keys("*"));
        System.out.println("要删除的缓存key"+keys);
        redisTemplate.delete(keys);
        switch (deptParent)
        {
            case "jwd":
            {
                String jwd = JSONArray.toJSONString(params.get("attachment"));
                JWDEmpEntity jwdEmpEntity = JSONArray.parseObject(jwd,JWDEmpEntity.class);
                jwdService.update(jwdEmpEntity,new QueryWrapper<JWDEmpEntity>().eq("emp_id",jwdEmpEntity.getEmpId()));
            }
            break;
            case "kyd":
                {
                    String kyd = JSONArray.toJSONString(params.get("attachment"));
                    KYDEmpEntity kydEmpEntity = JSONArray.parseObject(kyd,KYDEmpEntity.class);
                    kydService.update(kydEmpEntity,new QueryWrapper<KYDEmpEntity>().eq("emp_id",kydEmpEntity.getEmpId()));
                }
            break;
        }
    }

    public EmpEntity queryBaseEmp(Long empId)
    {
        EmpEntity emp = this.getById(empId);
        Gender gender = genderService.queryValue(emp.getGender());
        Status status = statusService.queryValue(emp.getStatus());
        emp.setStatusStr(status.getStatusValue());
        emp.setGenderStr(gender.getGenderValue());
        return emp;
    }
}
